package top.lixunda.ecommerce.server.user.api.entity.dto;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.ImmutableMap;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.business.api.condition.ILambdaQueryWrapperDTO;
import top.lixunda.ecommerce.server.business.api.entity.dto.OrderByDTO;
import top.lixunda.ecommerce.server.user.api.entity.db.BusinessTaskDO;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 待办任务信息添加查询DTO
 *
 * @author lixunda
 * @version time:2020/4/13 14:17
 */
@ApiModel("待办任务信息添加查询DTO")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
public class BusinessTaskQueryDTO extends OrderByDTO
        implements ILambdaQueryWrapperDTO<BusinessTaskDO> {

    /**
     * 任务编号
     */
    @ApiModelProperty("任务编号")
    private List<Integer> taskId;

    /**
     * 任务名称，唯一区分一个任务，如订单发货
     */
    @ApiModelProperty("任务名称")
    private List<String> taskName;

    /**
     * 菜单编码，菜单地址，点击代办事项跳转页面
     */
    @ApiModelProperty("菜单编码，菜单地址")
    private List<String> menuCode;

    /**
     * 业务主键，如订单发货业务为订单编号
     */
    @ApiModelProperty("业务主键")
    private List<Integer> businessId;

    /**
     * 创建人员编号
     */
    @ApiModelProperty("创建人员编号")
    private List<Integer> createUserId;

    /**
     * 创建人员类型
     */
    @ApiModelProperty("创建人员类型")
    private List<String> createUserType;

    /**
     * 创建时间
     */
    @ApiModelProperty("创建时间")
    private LocalDateTime createTimeBegin;

    /**
     * 创建时间
     */
    @ApiModelProperty("创建时间")
    private LocalDateTime createTimeEnd;

    /**
     * 分配模式，快速分配和全部分配
     */
    @ApiModelProperty("分配模式，快速分配和全部分配")
    private List<String> allotType;

    /**
     * 消费模式，单一抢占完成和全部完成
     */
    @ApiModelProperty("消费模式，单一抢占完成和全部完成")
    private List<String> consumeMode;

    /**
     * 任务是否完成，0 未完成 1 完成
     */
    @ApiModelProperty("任务是否完成，0 未完成 1 完成")
    private Integer consumeFlag;

    /**
     * 消费人员编号，即完成任务的人员编号
     */
    @ApiModelProperty("消费人员编号，即完成任务的人员编号")
    private List<Integer> consumeUserId;

    /**
     * 消费人员类型，完成任务的人员类型
     */
    @ApiModelProperty("消费人员类型，完成任务的人员类型")
    private List<String> consumeUserType;

    /**
     * 消费时间，任务完成时间
     */
    @ApiModelProperty("消费时间，任务完成时间")
    private LocalDateTime consumeTimeBegin;

    /**
     * 消费时间，任务完成时间
     */
    @ApiModelProperty("消费时间，任务完成时间")
    private LocalDateTime consumeTimeEnd;

    /**
     * 是否催办
     */
    @ApiModelProperty("是否催办")
    private Integer urgeFlag;

    /**
     * 催办时间模式，时长和固定时间
     */
    @ApiModelProperty("催办时间模式，时长和固定时间")
    private List<String> urgeTimeMode;

    /**
     * 固定时间模式，在此时间之后进行催办
     */
    @ApiModelProperty("固定时间模式，在此时间之后进行催办")
    private LocalDateTime urgeTimeBegin;

    /**
     * 固定时间模式，在此时间之后进行催办
     */
    @ApiModelProperty("固定时间模式，在此时间之后进行催办")
    private LocalDateTime urgeTimeEnd;

    /**
     * 时长时间模式，在创建任务时长后进行催办，单位秒
     */
    @ApiModelProperty("时长时间模式，在创建任务时长后进行催办，单位秒")
    private Long urgeTimeLengthBegin;

    /**
     * 时长时间模式，在创建任务时长后进行催办，单位秒
     */
    @ApiModelProperty("时长时间模式，在创建任务时长后进行催办，单位秒")
    private Long urgeTimeLengthEnd;

    /**
     * 是否短信推送任务
     */
    @ApiModelProperty("是否短信推送任务")
    private Integer pushPhoneFlag;

    /**
     * 是否邮件推送任务
     */
    @ApiModelProperty("是否邮件推送任务")
    private Integer pushEmailFlag;

    /**
     * 是否站内推送任务
     */
    @ApiModelProperty("是否站内推送任务")
    private Integer pushWebFlag;

    /**
     * 扩展属性1
     */
    @ApiModelProperty("扩展属性1")
    private List<Long> appLong1;

    /**
     * 扩展属性2
     */
    @ApiModelProperty("扩展属性2")
    private List<Long> appLong2;

    /**
     * 扩展属性3
     */
    @ApiModelProperty("扩展属性3")
    private List<Long> appLong3;

    /**
     * 字符串扩展属性1
     */
    @ApiModelProperty("字符串扩展属性1")
    private List<String> appString1;

    /**
     * 字符串扩展属性2
     */
    @ApiModelProperty("字符串扩展属性2")
    private List<String> appString2;

    /**
     * 字符串扩展属性3
     */
    @ApiModelProperty("字符串扩展属性3")
    private List<String> appString3;

    /**
     * 字符串扩展属性4
     */
    @ApiModelProperty("字符串扩展属性4")
    private List<String> appString4;

    /**
     * 字符串扩展属性5
     */
    @ApiModelProperty("字符串扩展属性5")
    private List<String> appString5;

    /**
     * 更新人员编号，一般是创建人员，取消人员，完成任务的最后一个人员，发生异常的人员
     */
    @ApiModelProperty("更新人员编号")
    private List<Integer> updateUserId;

    /**
     * 更新人员类型
     */
    @ApiModelProperty("更新人员类型")
    private List<String> updateUserType;

    /**
     * 任务状态，正常，取消，完成，异常，删除
     */
    @ApiModelProperty("任务状态，正常，取消，完成，异常，删除")
    private List<String> state;

    /**
     * 排序字段映射
     */
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    private static final Map<String, SFunction<BusinessTaskDO, ?>> COLUMNS =
            new ImmutableMap.Builder<String, SFunction<BusinessTaskDO, ?>>()
                    .put("taskId", BusinessTaskDO::getTaskId)
                    .put("taskName", BusinessTaskDO::getTaskName)
                    .put("menuCode", BusinessTaskDO::getMenuCode)
                    .put("businessId", BusinessTaskDO::getBusinessId)
                    .put("createUserId", BusinessTaskDO::getCreateUserId)
                    .put("createUserName", BusinessTaskDO::getCreateUserName)
                    .put("createUserType", BusinessTaskDO::getCreateUserType)
                    .put("createTime", BusinessTaskDO::getCreateTime)
                    .put("allotType", BusinessTaskDO::getAllotType)
                    .put("consumeMode", BusinessTaskDO::getConsumeMode)
                    .put("consumeFlag", BusinessTaskDO::getConsumeFlag)
                    .put("consumeUserId", BusinessTaskDO::getConsumeUserId)
                    .put("consumeUserName", BusinessTaskDO::getConsumeUserName)
                    .put("consumeUserType", BusinessTaskDO::getConsumeUserType)
                    .put("consumeTime", BusinessTaskDO::getConsumeTime)
                    .put("urgeFlag", BusinessTaskDO::getUrgeFlag)
                    .put("urgeTimeMode", BusinessTaskDO::getUrgeTimeMode)
                    .put("urgeTime", BusinessTaskDO::getUrgeTime)
                    .put("urgeTimeLength", BusinessTaskDO::getUrgeTimeLength)
                    .put("description", BusinessTaskDO::getDescription)
                    .put("pushPhoneFlag", BusinessTaskDO::getPushPhoneFlag)
                    .put("pushEmailFlag", BusinessTaskDO::getPushEmailFlag)
                    .put("pushWebFlag", BusinessTaskDO::getPushWebFlag)
                    .put("pushTitle", BusinessTaskDO::getPushTitle)
                    .put("pushContent", BusinessTaskDO::getPushContent)
                    .put("pushUrl", BusinessTaskDO::getPushUrl)
                    .put("appLong1", BusinessTaskDO::getAppLong1)
                    .put("appLong2", BusinessTaskDO::getAppLong2)
                    .put("appLong3", BusinessTaskDO::getAppLong3)
                    .put("appString1", BusinessTaskDO::getAppLong1)
                    .put("appString2", BusinessTaskDO::getAppString2)
                    .put("appString3", BusinessTaskDO::getAppString3)
                    .put("appString4", BusinessTaskDO::getAppString4)
                    .put("appString5", BusinessTaskDO::getAppString5)
                    .put("updateUserId", BusinessTaskDO::getUpdateUserId)
                    .put("updateUserName", BusinessTaskDO::getUpdateUserName)
                    .put("updateUserType", BusinessTaskDO::getUpdateUserType)
                    .put("updateTime", BusinessTaskDO::getUpdateTime)
                    .put("state", BusinessTaskDO::getState)
                    .put("remark", BusinessTaskDO::getRemark)
                    .build();

    /**
     * 将当前用于查询的DTO中的查询数据转换为 LambdaQuerySqlWrapper
     *
     * @return 条件构造器 LambdaQuerySqlWrapper
     */
    @SuppressWarnings("AlibabaMethodTooLong")
    @Override
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public LambdaQueryWrapper<BusinessTaskDO> toWrapper() {
        LambdaQueryWrapper<BusinessTaskDO> wrapper = new LambdaQueryWrapper<>();
        // 任务编号
        if (ObjectValidators.isNotEmpty(taskId)) {
            wrapper.and(innerWrapper -> taskId.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getTaskId, item)));
        }
        // 任务名称
        if (ObjectValidators.isNotEmpty(taskName)) {
            wrapper.and(innerWrapper -> taskName.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getTaskName, item)));
        }
        // 菜单编码，菜单地址
        if (ObjectValidators.isNotEmpty(menuCode)) {
            wrapper.and(innerWrapper -> menuCode.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getMenuCode, item)));
        }
        // 业务主键
        if (ObjectValidators.isNotEmpty(businessId)) {
            wrapper.and(innerWrapper -> businessId.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getBusinessId, item)));
        }
        // 创建人员编号
        if (ObjectValidators.isNotEmpty(createUserId)) {
            wrapper.and(innerWrapper -> createUserId.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getCreateUserId, item)));
        }
        // 创建人员类型
        if (ObjectValidators.isNotEmpty(createUserType)) {
            wrapper.and(innerWrapper -> createUserType.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getCreateUserType, item)));
        }
        // 创建时间
        if (ObjectValidators.isNotEmpty(createTimeBegin)) {
            wrapper.ge(BusinessTaskDO::getCreateTime, createTimeBegin);
        }
        if (ObjectValidators.isNotEmpty(createTimeEnd)) {
            wrapper.le(BusinessTaskDO::getCreateTime, createTimeEnd);
        }
        // 分配模式，快速分配和全部分配
        if (ObjectValidators.isNotEmpty(allotType)) {
            wrapper.and(innerWrapper -> allotType.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getAllotType, item)));
        }
        // 消费模式
        if (ObjectValidators.isNotEmpty(consumeMode)) {
            wrapper.and(innerWrapper -> consumeMode.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getConsumeMode, item)));
        }
        // 任务是否完成
        if (ObjectValidators.isNotEmpty(consumeFlag)) {
            wrapper.eq(BusinessTaskDO::getConsumeFlag, consumeFlag);
        }
        // 消费人员编号
        if (ObjectValidators.isNotEmpty(consumeUserId)) {
            wrapper.and(innerWrapper -> consumeUserId.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getConsumeUserId, item)));
        }
        // 消费人员类型
        if (ObjectValidators.isNotEmpty(consumeUserType)) {
            wrapper.and(innerWrapper -> consumeUserType.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getConsumeUserType, item)));
        }
        // 消费时间
        if (ObjectValidators.isNotEmpty(consumeTimeBegin)) {
            wrapper.ge(BusinessTaskDO::getConsumeTime, consumeTimeBegin);
        }
        if (ObjectValidators.isNotEmpty(consumeTimeEnd)) {
            wrapper.le(BusinessTaskDO::getConsumeTime, consumeTimeEnd);
        }
        // 是否催办
        if (ObjectValidators.isNotEmpty(urgeFlag)) {
            wrapper.eq(BusinessTaskDO::getUrgeFlag, urgeFlag);
        }
        // 催办时间模式
        if (ObjectValidators.isNotEmpty(urgeTimeMode)) {
            wrapper.and(innerWrapper -> urgeTimeMode.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getUrgeTimeMode, item)));
        }
        // 固定时间模式，在此时间之后进行催办
        if (ObjectValidators.isNotEmpty(urgeTimeBegin)) {
            wrapper.ge(BusinessTaskDO::getUrgeTime, urgeTimeBegin);
        }
        if (ObjectValidators.isNotEmpty(urgeTimeEnd)) {
            wrapper.le(BusinessTaskDO::getUrgeTime, urgeTimeEnd);
        }
        // 时长时间模式
        if (ObjectValidators.isNotEmpty(urgeTimeLengthBegin)) {
            wrapper.ge(BusinessTaskDO::getUrgeTimeLength, urgeTimeLengthBegin);
        }
        if (ObjectValidators.isNotEmpty(urgeTimeLengthEnd)) {
            wrapper.le(BusinessTaskDO::getUrgeTimeLength, urgeTimeLengthEnd);
        }
        // 是否短信推送任务
        if (ObjectValidators.isNotEmpty(pushPhoneFlag)) {
            wrapper.eq(BusinessTaskDO::getPushPhoneFlag, pushPhoneFlag);
        }
        // 是否邮件推送任务
        if (ObjectValidators.isNotEmpty(pushEmailFlag)) {
            wrapper.eq(BusinessTaskDO::getPushEmailFlag, pushEmailFlag);
        }
        // 是否站内推送任务
        if (ObjectValidators.isNotEmpty(pushWebFlag)) {
            wrapper.eq(BusinessTaskDO::getPushEmailFlag, pushWebFlag);
        }

        // 扩展属性1
        if (ObjectValidators.isNotEmpty(appLong1)) {
            wrapper.and(innerWrapper -> appLong1.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getAppLong1, item)));
        }
        // 扩展属性2
        if (ObjectValidators.isNotEmpty(appLong2)) {
            wrapper.and(innerWrapper -> appLong2.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getAppLong2, item)));
        }
        // 扩展属性3
        if (ObjectValidators.isNotEmpty(appLong3)) {
            wrapper.and(innerWrapper -> appLong3.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getAppLong3, item)));
        }
        // 字符串扩展属性1
        if (ObjectValidators.isNotEmpty(appString1)) {
            wrapper.and(innerWrapper -> appString1.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getAppString1, item)));
        }
        // 字符串扩展属性2
        if (ObjectValidators.isNotEmpty(appString2)) {
            wrapper.and(innerWrapper -> appString2.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getAppString2, item)));
        }
        // 字符串扩展属性3
        if (ObjectValidators.isNotEmpty(appString3)) {
            wrapper.and(innerWrapper -> appString3.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getAppString3, item)));
        }
        // 字符串扩展属性4
        if (ObjectValidators.isNotEmpty(appString4)) {
            wrapper.and(innerWrapper -> appString4.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getAppString4, item)));
        }
        // 字符串扩展属性5
        if (ObjectValidators.isNotEmpty(appString5)) {
            wrapper.and(innerWrapper -> appString5.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getAppString5, item)));
        }
        // 字符串扩展属性4
        if (ObjectValidators.isNotEmpty(urgeTimeMode)) {
            wrapper.and(innerWrapper -> urgeTimeMode.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getUrgeTimeMode, item)));
        }

        // 更新人员编号
        if (ObjectValidators.isNotEmpty(updateUserId)) {
            wrapper.and(innerWrapper -> updateUserId.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getUpdateUserId, item)));
        }
        // 更新人员类型
        if (ObjectValidators.isNotEmpty(updateUserType)) {
            wrapper.and(innerWrapper -> updateUserType.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getUpdateUserType, item)));
        }
        // 任务状态，正常，取消，完成，异常，删除
        if (ObjectValidators.isNotEmpty(state)) {
            wrapper.and(innerWrapper -> state.forEach(item ->
                    innerWrapper.eq(BusinessTaskDO::getState, item)));
        }

        dealWithOrderBy(wrapper, COLUMNS);
        return wrapper;
    }
}
